<?php

namespace cf;

require_once 'string.php';

final class File
{
   function __construct($fname, $mode='r')
   {
      $this->h = fopen($fname, $mode);
      if (false === $this->h) {
         throw new Exception("Can't open file $fname");
      }
   }

   function __destruct()
   {
      fclose($this->h);
   }

   public function handle() 
   {
      return $this->h;
   }

   public function readLine()
   {
      while(($s = fgets($this->h)) !== false)
      {
         $s = trim($s);
         if (strlen($s)) {
            return $s;
         }
      }
      return false;
   }

   /**
      @return   array of non-empty lines from file
   */
   public function toArray()
   {
      $a = array();
      while ($s = $this->readLine()) {
         $a[] = $s;
      }
      return $a;
   }

   /**
      @param $field  name of send field - key in $_FILES array
      @param $path   store uploaded file to
      @param $name   new name of file (without extension) or keep original if empty
      @param $allowedTypes  check file type to be one of these or skip if empty array
      @param $maxSizeBytes  skip if =0

      @return  full path to stored file or null if an error occured
   */
   static public function upload($field, $path, $name=null, $allowedTypes=array(), $maxSizeBytes=0)
   {
      if (!array_key_exists($field,$_FILES)) {
         return null;
      }

      $params = $_FILES[$field];
      $fnm = $params['name'];
      $err = $params['error'];

	   if ($err != UPLOAD_ERR_OK) 
      {
			if ($err == UPLOAD_ERR_NO_FILE) {
				return null;
			}
			else if ($err == UPLOAD_ERR_INI_SIZE) {
				throw new Exception("File upload error: file size exceeds 'upload_max_filesize' parameter set in php.ini");
			}
			throw new Exception("File upload error: error code [$err]");
		}
		
		if (!is_uploaded_file($params['tmp_name'])) {
			throw new Exception('File upload error: file was not actually uploaded');
		}
	
      if ($maxSizeBytes && $params['size'] > $maxSizeBytes) 
		{
			throw new Exception("File upload error: file [$fnm] exceeds maximum size");
		}

      $ftype = strtolower(substr(strrchr($params['name'],'.'),1));
      if (!empty($allowedTypes) && !in_array($ftype,$allowedTypes)) {
         throw new Exception("File upload error: invalid file type [$ftype]");
      }

      $fnm = $name ? "$name.$ftype" : $fnm;
      $savePath = String::append($path,'/').$fnm;

      if (!move_uploaded_file($params['tmp_name'], $savePath)) {
         throw new Exception('File upload error: can not move uploaded file');
      }

      chmod($savePath, 0644);

      return $savePath;
   }

   static public function is_file($fname)
   {
      return is_file($fname);
   }

   static public function is_link($fname)
   {
      return is_link($fname);
   }

   static public function is_dir($fname)
   {
      return is_dir($fname);
   }
   static public function exist($fname)
   {
      return is_file($fname) || is_link($fname) || is_dir($fname);
   }


   private $h = false;
};

?>
